package com.pci.netty.util;

import cn.hutool.crypto.digest.DigestUtil;
import com.pci.netty.enums.ReplyCodeEnum;
import com.pci.netty.enums.ReplyMarkEnum;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;

/**
 * 响应
 */
public class ResponseUtils {
    /**
     * 报文格式错误
     *
     * @param header 包头
     * @param body   包体
     * @param ctx
     */
    public static void dataError(byte[] header, byte[] body, ChannelHandlerContext ctx) {
        response(header, body, ReplyCodeEnum.DATA_ERROR.getCode(), ctx);
    }

    /**
     * 报文格式错误
     *
     * @param data 包头和包体
     * @param ctx
     */
    public static void dataError(byte[] data, ChannelHandlerContext ctx) {
        int bodyLength = data.length - 16;
        byte[] head = new byte[16];
        byte[] body = new byte[bodyLength];
        System.arraycopy(data, 0, head, 0, 16);
        System.arraycopy(data, 16, body, 0, bodyLength);
        response(head, body, ReplyCodeEnum.DATA_ERROR.getCode(), ctx);
    }

    /**
     * 重复应答
     *
     * @param header
     * @param body
     * @param ctx
     */
    public static void repetitionAsk(byte[] header, byte[] body, ChannelHandlerContext ctx) {
        response(header, body, ReplyCodeEnum.REPETITION.getCode(), ctx);
    }

    /**
     * 目标结点不可达
     *
     * @param header
     * @param body
     * @param ctx
     */
    public static void unReachable(byte[] header, byte[] body, ChannelHandlerContext ctx) {
        response(header, body, ReplyCodeEnum.UNREACHABLE.getCode(), ctx);
    }

    /**
     * 通讯超时
     *
     * @param header
     * @param body
     * @param ctx
     */
    public static void timeOut(byte[] header, byte[] body, ChannelHandlerContext ctx) {
        response(header, body, ReplyCodeEnum.TIMEOUT.getCode(), ctx);
    }

    /**
     * 成功
     *
     * @param header
     * @param body
     * @param ctx
     */
    public static void successful(byte[] header, byte[] body, ChannelHandlerContext ctx) {
        response(header, body, ReplyCodeEnum.SUCCESS.getCode(), ctx);
    }

    /**
     * 响应消息
     *
     * @param header
     * @param body
     * @param responseCode
     * @param ctx
     */
    public static void response(byte[] header, byte[] body, byte responseCode, ChannelHandlerContext ctx) {
        System.arraycopy(header, 2, header, 6, 4);
        int len = header.length;
        header[len - 1] = responseCode;
        header[len - 2] = ReplyMarkEnum.RESPONSE.getCode();
        byte[] data = header;
        ByteBuf byteBuf = Unpooled.buffer(32);
        byteBuf.writeBytes(header);//写包头
        if (body != null) {
            body = AESUtils.encrypt(body);//aes加密
            data = new byte[body.length + len];
            System.arraycopy(body, 0, data, len, body.length);
            byteBuf.writeBytes(body);//写包体
        }
        byteBuf.writeBytes(DigestUtil.md5(data));//写校验码
        ctx.writeAndFlush(byteBuf);
    }

}
